﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using App.Common;
using QxFramework.Core;
using DG.Tweening;
using System;

public class MonoBase : MonoBehaviour
{
    public enum MonoTag
    { 
        All,
        Player,
        Enemy,
    }

    private bool _canMoveUp;
    private bool _canMoveDown;
    private bool _canMoveLeft;
    private bool _canMoveRight;

    [HideInInspector]
    public Mono monoBase
    {
        get
        {
            return GameMgr.Get<IMonoManager>().GetMono(gameObject.name);
        }
    }

    public virtual void Awake()
    {
    }
    public virtual void OnEnable()
    {
        foreach (Transform child in transform.Find("Sprite/Buff"))
        {
            Destroy(child.gameObject);
        }
        IsChangingColor = false;
    }
    public virtual void OnDisable()
    {

    }
    public virtual void OnDestroy()
    {

    }

    public virtual void Update()
    {
        ColorControl();
        DamageAnim();
        BuffAffect();
        UpdateBuffEffect();
        CollideControll();
        LayerSet();
        UpdateFireText();
    }
    //设置层（遮挡效果
    private void LayerSet()
    {
        GetComponentInChildren<SpriteRenderer>().sortingOrder = 100 - (int)(transform.position.y * 2);
    }
    private void UpdateFireText()
    {
        if (TextTimer < 0)
        {
            TextTimer = 0;
        }
        else
        {
            TextTimer -= Time.deltaTime;
        }
    }
    public virtual void LateUpdate()
    {
        float[] parallel = { -0.2f, 0.2f };
        int layerMask = LayerMask.GetMask("Obstacle");
        float wide = 0.1f;
        var pos = monoBase.Position;
        _canMoveUp = true;
        _canMoveDown = true;
        _canMoveLeft = true;
        _canMoveRight = true;
        for (int k = 0; k < 2; k++)
        {
            //下上左右检测墙
            Vector2[] dirStart = { new Vector2(parallel[k], -wide), new Vector2(parallel[k], wide), new Vector2(-wide, parallel[k]), new Vector2(wide, parallel[k]) };
            Vector2[] dirEnd = { new Vector2(parallel[k], -1f), new Vector2(parallel[k], 1f), new Vector2(-1f, parallel[k]), new Vector2(1f, parallel[k]) };
            for (int i = 0; i < 4; i++)
            {
                Vector3 posStart = new Vector3(pos.x + dirStart[i].x, pos.y + dirStart[i].y, pos.z + 1f);
                Vector3 posEnd = new Vector3(pos.x + dirEnd[i].x, pos.y + dirEnd[i].y, pos.z + 1f);
                //Debug.DrawRay(posStart, posEnd - posStart, new Color(0, 0, 1));
                RaycastHit2D hit = Physics2D.Raycast(posStart, posEnd - posStart, 0.5f, layerMask);
                SetCanMoveDirection((canMoveDir)i, (hit.collider == null) && GetCanMoveDirection((canMoveDir)i));
                if (hit.collider != null)
                {
                    monoBase.Position = FixDirection(pos, hit.collider.bounds.center, hit.collider.bounds.size, GetComponent<CircleCollider2D>().radius, dirEnd[i]);
                }
            }
        }
    }
    private Vector3 FixDirection(Vector3 pos,Vector3 collPos,Vector3 collSize,float radius,Vector2 dirEnd)
    {
        if (monoBase.monoRealtimeStatus.IsFrozen>0)
        {
            return pos;
        }
        if (!_canMoveUp && collPos.y - pos.y < collSize.y / 2 + radius && dirEnd.y == 1)
            pos.y = collPos.y - collSize.y / 2 - radius - 0.001f;
        if (!_canMoveDown && pos.y - collPos.y < collSize.y / 2 + radius && dirEnd.y == -1)
            pos.y = collPos.y + collSize.y / 2 + radius + 0.001f;
        if (!_canMoveLeft && pos.x - collPos.x < collSize.x / 2 + radius && dirEnd.x == -1)
            pos.x = collPos.x + collSize.x / 2 + radius + 0.001f;
        if (!_canMoveRight && collPos.x - pos.x < collSize.x / 2 + radius && dirEnd.x == 1)
            pos.x = collPos.x - collSize.x / 2 - radius - 0.001f;
        return pos;
    }

    public void CollideControll()
    {
        if (GameMgr.Get<IMonoManager>().GetAllMono()._MonoList.ContainsKey(gameObject.name))
        {
            GetComponent<CircleCollider2D>().enabled = !monoBase.monoRealtimeStatus.IsDying;
            GetComponent<CircleCollider2D>().enabled = !monoBase.monoRealtimeStatus.IsInvincible;
        }
        else
        {
            GetComponent<CircleCollider2D>().enabled = false;
        }
    }
    /// <summary>
    /// 转向控制
    /// </summary>
    public void SpriteDirectFix()
    {
        float angle = (monoBase.Direction.x < 0) ? 0 : 180;
        transform.Find("Sprite").eulerAngles = new Vector3(0, angle, 0);
    }

    //回合结束
    public void BuffArrange()
    {
        if (monoBase.BuffList.ContainsKey(5))
        {
            monoBase.BuffList[5].buffTime.CurrentTime += 2;
        }
        if (monoBase.BuffList.ContainsKey(6))
        {
            monoBase.BuffList[6].buffTime.CurrentTime += 2;
        }
        if (monoBase.monoRealtimeStatus.IsFrozen > 0)
        {
            monoBase.monoRealtimeStatus.IsFrozen -= 2;
        }
    }

    /// <summary>
    /// 使用技能
    /// </summary>
    public virtual void UseSkill(Vector3 Direct,int SkillID,out bool ShootSuccess)
    {
        ShootSuccess = true;
    }
    float TextTimer = 0f;
    public bool SkillJudge(Vector3 Direct, int SkillID, out int FloorMP)
    {
        int AttrID = (int)monoBase.SkillList[SkillID].SkillAttr;
        FloorMP = (AttrID == 0)?Data.Instance.TableAgent.GetInt("AllBuff", GetAttrID().ToString(), "MPPlus"): Data.Instance.TableAgent.GetInt("AllBuff", AttrID.ToString(), "MPPlus");
        if (Direct == new Vector3(0, 0, 1f))
            return false;
        if (monoBase.monoRealtimeStatus.LostingRate > 0)
        {
            return false;
        }
        if (monoBase.SkillList[SkillID].CD.CurrentCD > 0)
        {
            return false;
        }
        if (monoBase.monoRealtimeStatus.IsSteamed && monoBase.Attr != MonoAttribute.Steam)
        {
            if (gameObject.name.Contains("Player"))
            {
                if (TextTimer <= 0)
                {
                    TextTimer = 0.4f;
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "致盲", Color.white);
                }
            }
            else
            {
                GameMgr.Get<IBattleManager>().EndThisTurn();
            }
            return false;
        }
        if (monoBase.monoRealtimeStatus.IsElectriciting && monoBase.Attr != MonoAttribute.Electric)
        {
            if (gameObject.name.Contains("Player"))
            {
                if (TextTimer <= 0)
                {
                    TextTimer = 0.4f;
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "麻痹", Color.white);
                }
            }
            else
            {
                GameMgr.Get<IBattleManager>().EndThisTurn();
            }
            return false;
        }
        if (monoBase.monoRealtimeStatus.IsFrozen > 0 && monoBase.Attr != MonoAttribute.Ice)
        {
            if (gameObject.name.Contains("Player"))
            {
                if (TextTimer <= 0)
                {
                    TextTimer = 0.4f;
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "冻结", Color.white);
                }
            }
            else
            {
                GameMgr.Get<IBattleManager>().EndThisTurn();
            }
            return false;
        }
        if (monoBase.MPData.MPValue < monoBase.SkillList[SkillID].skillMPData.MPUse + FloorMP)
        {
            if (gameObject.name.Contains("Player"))
            {
                if (TextTimer <= 0)
                {
                    TextTimer = 0.4f;
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "法术不足", Color.white);
                }
            }
            return false;
        }
        if (!CDingJudge())
        {
            return false;
        }
        if (!TipsJudge())
        {
            return false;
        }
        return true;
    }
    public void UseSkillJudge(Vector3 Direct,int SkillID)
    {
        if (!SkillJudge(Direct, SkillID, out int FloorMP))
            return;
        UseSkill(Direct, SkillID, out bool ShootSuccess);
        if (ShootSuccess)
        {
            monoBase.SkillList[SkillID].CD.CurrentCD = monoBase.SkillList[SkillID].CD.CDTime;
            GameMgr.Get<IMonoManager>().ChangeMPValue(monoBase, monoBase.SkillList[SkillID], -monoBase.SkillList[SkillID].skillMPData.MPUse - FloorMP);
        }
    }
    public bool UseLPJudge(int value)
    {
        if(monoBase.LPData.LPValue < Mathf.Abs(value))
        {
            return false;
        }
        if (monoBase.monoRealtimeStatus.IsInvincible)
        {
            return false;
        }
        if (monoBase.monoRealtimeStatus.IsCounterAttack)
        {
            return false;
        }
        GameMgr.Get<IMonoManager>().ChangeLPValue(monoBase, value);
        return true;
    }
    /// <summary>
    /// 得到当前脚下的地砖
    /// </summary>
    /// <returns></returns>
    public MapEditorBase.MapGround GetNowGround()
    {
        return GetNowGround(gameObject.transform.position);
    }
    public MapEditorBase.MapGround GetNowGround(Vector3 target)
    {
        return GameMgr.Get<IMapManager>().GetNearestGround(target);
    }

    public List<Vector3> GetRoadToThePosition(Vector3 target)
    {
        List<Vector3> result = new List<Vector3>();
        var ground = GameMgr.Get<IMapManager>().GetNearestGround(target);
        if (ground == null)
            return null;
        target = ground.position;
        int targetKey = GameMgr.Get<IMapManager>().GetHashPosKey(target);
        if (GetNowGround() == null)
            return null;
        var room = GameMgr.Get<IMapManager>().GetCertainRoom(GameMgr.Get<IMapManager>().GetRoomID(GetNowGround()));
        var obstacle = GetObstacleGround(room.roomID);
        //下左上右
        Vector3[] vec = { new Vector3(0, -2.5f, 0), new Vector3(-2.5f, 0, 0), new Vector3(0, 2.5f, 0), new Vector3(2.5f, 0, 0) };
        List<AStart> openList = new List<AStart>();
        Dictionary<int, AStart> openDic = new Dictionary<int, AStart>();
        List<int> closeList = new List<int>();
        openList.Add(new AStart(GetNowGround().position, null));
        AStart now = openList[0];
        int nowKey = GameMgr.Get<IMapManager>().GetHashPosKey(now.position);
        openDic.Add(GameMgr.Get<IMapManager>().GetHashPosKey(now.position), now);

        while (nowKey != targetKey)
        {
            now = GetMinNode(openList);
            if (now == null)
                return null;
            nowKey = GameMgr.Get<IMapManager>().GetHashPosKey(now.position);
            if (nowKey == targetKey)
                break;
            if (closeList.Contains(nowKey))
                continue;
            closeList.Add(nowKey);
            for (int i = 0; i < 4; i++)
            {
                float cost = 2.5f + now.cost;
                Vector3 next = now.position + vec[i];
                int key = GameMgr.Get<IMapManager>().GetHashPosKey(next);
                KeyValuePair<int, int> obs = new KeyValuePair<int, int>(nowKey > key ? key : nowKey, nowKey < key ? key : nowKey); 
                if (!room.mapGroundPos.ContainsKey(key) || closeList.Contains(key) || obstacle.Contains(obs))
                    continue;
                float est = GetDistance(next, target);
                AStart temp = new AStart(next, now, cost + est, cost, est);
                if (!openDic.ContainsKey(key))
                {
                    openDic.Add(key, temp);
                    openList.Add(temp);
                }
                else
                    openDic[key] = temp.sum > openDic[key].sum ? openDic[key] : temp;
            }

        }
        var node = openDic[targetKey];
        while (node.parent != null)
        {
            result.Add(node.position);
            node = node.parent;
        }
        return result;
    }
    private float GetDistance(Vector3 pos1,Vector3 pos2)
    {
        return Mathf.Sqrt((pos1.x - pos2.x) * (pos1.x - pos2.x) + (pos1.y - pos2.y) * (pos1.y - pos2.y));
    }
    public AStart GetMinNode(List<AStart> aStarts)
    {
        int num = 0;
        if (aStarts.Count == 0)
            return null;
        AStart result = aStarts[0];
        for (int i = 0; i < aStarts.Count; i++)
        {
            if(aStarts[i].sum < result.sum)
            {
                num = i;
                result = aStarts[i];
            }
        }
        aStarts.RemoveAt(num);
        return result;
    }
    public List<KeyValuePair<int, int>> GetObstacleGround(int roomID)
    {
        var room = GameMgr.Get<IMapManager>().GetCertainRoom(roomID);
//         List<Vector3> debug = new List<Vector3>();
        var wall = room.mapWalls;
        List<KeyValuePair<int, int>> result = new List<KeyValuePair<int, int>>();
        //下左上右
        Vector3[] vec = { new Vector3(0, -2.5f, 0), new Vector3(-2.5f, 0, 0), new Vector3(0, 2.5f, 0), new Vector3(2.5f, 0, 0) };
        foreach (var item in wall)
        {
            var pos = GetNowGround(item.position).position;
            Vector3 temp = new Vector3();
            if (item.sceneType == SceneType.HorWall)
            {
                if (pos.y > item.position.y)
                    temp = pos + vec[0];
                else
                    temp = pos + vec[2];
            }
            else if (item.sceneType == SceneType.VerWall)
            {
                if (pos.x > item.position.x)
                    temp = pos + vec[1];
                else
                    temp = pos + vec[3];
            }
            else if(item.sceneType == SceneType.Obstacle)
            {
                for (int i = 0; i < 4; i++)
                {
                    var t = pos + vec[i];
                    int k1 = GameMgr.Get<IMapManager>().GetHashPosKey(pos);
                    int k2 = GameMgr.Get<IMapManager>().GetHashPosKey(t);
                    if (room.mapGroundPos.ContainsKey(k1) && room.mapGroundPos[k1] != null && room.mapGroundPos.ContainsKey(k2) && room.mapGroundPos[k2] != null)
                    {
                        result.Add(new KeyValuePair<int, int>((k1 > k2 ? k2 : k1), (k1 > k2 ? k1 : k2)));
                    }
                }
                continue;
            }
            int key1 = GameMgr.Get<IMapManager>().GetHashPosKey(pos);
            int key2 = GameMgr.Get<IMapManager>().GetHashPosKey(temp);
            if (room.mapGroundPos.ContainsKey(key2) && room.mapGroundPos[key2] != null && room.mapGroundPos.ContainsKey(key1) && room.mapGroundPos[key1] != null)
            {
                result.Add(new KeyValuePair<int, int>((key1 > key2 ? key2 : key1), (key1 > key2 ? key1 : key2)));
//                 if (!debug.Contains(pos))
//                     debug.Add(pos); 
//                 if (!debug.Contains(temp))
//                     debug.Add(temp);
            }
        }

        return result;
    }
    public virtual bool CDingJudge()
    {
        return true;
    }
    public virtual bool TipsJudge()
    {
        return true;
    }
    private int GetAttrID()
    {
        switch (monoBase.Attr)
        {
            case MonoAttribute.None:
                return 0;
            case MonoAttribute.Fire:
                return 1;
            case MonoAttribute.Ice:
                return 2;
            case MonoAttribute.Shine:
                return 3;
            case MonoAttribute.Dark:
                return 4;
            case MonoAttribute.Steam:
                return 5;
            case MonoAttribute.Electric:
                return 6;
            case MonoAttribute.Oil:
                return 7;
            default:
                return 0;
        }
    }

    /// <summary>
    /// 判断友方
    /// </summary>
    public bool IsInLine(MonoTag tag, Vector2 Start, Vector2 Direct)
    {
        bool Alie = false;
        LayerMask MonoLayer = 1 << LayerMask.NameToLayer("Monos");
        RaycastHit2D hit = Physics2D.Raycast(Start + Direct.normalized * (GetComponent<CircleCollider2D>().radius + 0.05f), Direct, 1000, MonoLayer);
        if (!hit)
        {
            return false;
        }
        if (hit.collider.gameObject.tag == tag.ToString() && hit.collider.gameObject != gameObject)
        {
            Alie = true;
        }
        return Alie;
    }
    /// <summary>
    /// 判断障碍
    /// </summary>
    public bool IsObstacleInLine(Vector2 Start, Vector2 Direct,float distance,string fliterTag)
    {
        //小角度射两条射线
        LayerMask ObsLayer = (1 << LayerMask.NameToLayer("Obstacle"))| (1 << LayerMask.NameToLayer("Monos"));
        Vector2 dir1 = (Quaternion.AngleAxis(10, Vector3.forward) * (Direct.normalized * (GetComponent<CircleCollider2D>().radius + 0.05f)));
        Vector2 dir2 = Quaternion.AngleAxis(-10, Vector3.forward) * (Direct.normalized * (GetComponent<CircleCollider2D>().radius + 0.05f));
        Vector2 vec1 = Quaternion.AngleAxis(1, Vector3.forward) * Direct;
        Vector2 vec2 = Quaternion.AngleAxis(-1, Vector3.forward) * Direct;
        RaycastHit2D hit1 = Physics2D.Raycast(Start + dir1, vec1, distance, ObsLayer);
        RaycastHit2D hit2 = Physics2D.Raycast(Start + dir2, vec2, distance, ObsLayer);
        Debug.DrawRay(Start + dir1, vec1, Color.red, 0.2f);
        Debug.DrawRay(Start + dir2, vec2, Color.red, 0.2f);
        if (hit1)
        {
            if (hit1.collider.gameObject.tag != fliterTag)
            {
                return true;
            }
        }
        if (hit2)
        {
            if (hit2.collider.gameObject.tag != fliterTag)
            {
                return true;
            }
        }
        return false;
    }


    /// <summary>
    /// 基础移动逻辑
    /// </summary>
    public void MoveMonoByAngle(Vector3 Direction, float Speed)
    {
        Vector3 Direct = new Vector3(Mathf.Tan(Direction.z), Mathf.Atan(Direction.z), 0);
        GameMgr.Get<IMonoManager>().MoveMono(monoBase, Direct, Speed * FreezeRate);
    }
    public void MoveByDirection(Vector3 Direction, float Speed)
    {
        if (!GameMgr.Get<IBattleManager>().BattleMonoLPCheck(monoBase))
        {
            if (gameObject.name.Contains("Player"))
            {
                if (TextTimer <= 0)
                {
                    TextTimer = 0.4f;
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "体力不足", Color.white);
                }
            }
            return;
        }

        Direction = CheckDirection(Direction);
        GameMgr.Get<IMonoManager>().MoveMono(monoBase, Direction, Speed * FreezeRate);
    }
    private Vector3 CheckDirection(Vector3 vec)
    {
        if (!_canMoveUp && vec.y > 0)
            vec.y = 0;
        if (!_canMoveDown && vec.y < 0)
            vec.y = 0;
        if (!_canMoveLeft && vec.x < 0)
            vec.x = 0;
        if (!_canMoveRight && vec.x > 0)
            vec.x = 0;
        return vec;
    }
    private void SetCanMoveDirection(canMoveDir dir, bool canMove)
    {
        switch (dir)
        {
            case canMoveDir.Above:
                _canMoveUp = canMove;
                break;
            case canMoveDir.Below:
                _canMoveDown = canMove;
                break;
            case canMoveDir.Left:
                _canMoveLeft = canMove;
                break;
            case canMoveDir.Right:
                _canMoveRight = canMove;
                break;
        }
    }
    private bool GetCanMoveDirection(canMoveDir dir)
    {
        switch (dir)
        {
            case canMoveDir.Above:
                return _canMoveUp;
            case canMoveDir.Below:
                return _canMoveDown;
            case canMoveDir.Left:
                return _canMoveLeft;
            case canMoveDir.Right:
                return _canMoveRight;
        }
        return true;
    }

    /// <summary>
    /// 受伤
    /// </summary>
    public void GetDamage(int value)
    {
        DamagingTempTime = 0.5f;
        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase,-value);
    }
    private float DamagingTempTime;
    float TempTime;
    private void DamageAnim()
    {
        if (DamagingTempTime>0)
        {
            DamagingTempTime -= Time.deltaTime;
            if (TempTime <= 0)
            {
                TempTime = 0.05f;
                transform.Find("Sprite").GetComponent<SpriteRenderer>().enabled = !transform.Find("Sprite").GetComponent<SpriteRenderer>().enabled;
            }
            else
            {
                TempTime -= Time.deltaTime;
            }
        }
        else
        {
            DamagingTempTime = 0;
            TempTime = 0;
            transform.Find("Sprite").GetComponent<SpriteRenderer>().enabled = true;
        }
    }

    /// <summary>
    /// 范围判断
    /// </summary>
    public bool WithInRage(MonoTag tag,float range, out bool lostTarget,out Vector3 otherDirection, out GameObject Obj)
    {
        bool temp = GameMgr.Get<IMonoManager>().WithInRage(monoBase, monoBase.Position, tag, range, out bool LostTarget, out Vector3 Direct, out GameObject obj);
        Obj = obj;
        lostTarget = LostTarget;
        otherDirection = Direct;
        return temp;
    }

    /// <summary>
    /// 持续时间移动逻辑
    /// </summary>
    public void LastTimeMove(Vector3 Direct, float Speed, int Frame,Action action)
    {
        StartCoroutine(lastTimeMove(Direct, Speed, Frame, action));
    }
    private IEnumerator lastTimeMove(Vector3 Direct,float Speed, int Frame, Action action)
    {
        int i = 0;
        while (i < Frame)
        {
            if (Direct == new Vector3(0, 0, 1f))
                Speed = 0;
            Direct = CheckDirection(Direct);
            GameMgr.Get<IMonoManager>().MoveMono(monoBase, Direct, Speed * FreezeRate);
            i++;
            yield return 0;
        }
        if (action != null)
        {
            action.Invoke();
        }
    }

    public bool ItsYourTurn()
    {
        if (GameMgr.Get<IBattleManager>().GetBattleData().BlockInput)
        {
            return false;
        }
        if (GameMgr.Get<IBattleManager>().GetBattleData().InBattle)
        {
            return GameMgr.Get<IBattleManager>().GetBattleData().monos[GameMgr.Get<IBattleManager>().GetBattleData().CurrentID] == gameObject.name;
        }
        return true;
    }

    #region Buff效果相关
    [HideInInspector]
    public float FreezeRate = 1;
    float tmpTime = 0;
    private void BuffAffect()
    {
        if (!ItsYourTurn())
        {
            return;
        }
        if (!GameMgr.Get<ITimeManager>().IsTimeGoing())
        {
            return;
        }

        if (tmpTime <= 0)
        {
            tmpTime = 0.5f;//每x s判断一次buff效果
            FreezeRate = 1;

            monoBase.HPData.HPValue += monoBase.HPData.RecoverSpeed;

            foreach (int buffID in monoBase.BuffList.Keys)
            {
                if (buffID == 1)//火
                {
                    if (monoBase.Attr != MonoAttribute.Fire)
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, -((monoBase.Attr == MonoAttribute.Ice) ? 2 : 1) * (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    else
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "\n" + ((monoBase.Attr == MonoAttribute.Fire) ? "免疫" : "") + "燃烧", Data.Instance.PrintColor[0]);
                }
                if (buffID == 2)//冰
                {
                    if (monoBase.Attr != MonoAttribute.Ice)
                    {
                        FreezeRate = 1 - Data.Instance.TableAgent.GetFloat("Base", "IceReduceSpeed","Value")* monoBase.BuffList[buffID].buffOverride.CurrentOverride;
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, -((monoBase.Attr == MonoAttribute.Fire) ? 2 : 1) * (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    else
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "\n" + ((monoBase.Attr == MonoAttribute.Ice) ? "免疫" : "") + "寒冷", Data.Instance.PrintColor[1]);
                }
                if (buffID == 5)//蒸汽
                {
                    if (monoBase.Attr != MonoAttribute.Steam)
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, -((monoBase.Attr == MonoAttribute.Electric) ? 2 : 1) * (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    else
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "\n" + ((monoBase.Attr == MonoAttribute.Steam) ? "免疫" : "") + "致盲", Data.Instance.PrintColor[4]);
                }
                if (buffID == 6)//电
                {
                    if (monoBase.Attr != MonoAttribute.Electric)
                    {
                        FreezeRate = 0.01f;
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, -((monoBase.Attr == MonoAttribute.Steam) ? 2 : 1) * (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    else
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "\n" + ((monoBase.Attr == MonoAttribute.Electric) ? "免疫" : "") + "麻痹", Data.Instance.PrintColor[5]);
                }
                if (buffID == 7)//油
                {
                    if (monoBase.Attr != MonoAttribute.Oil)
                    {
                        FreezeRate = 1 - Data.Instance.TableAgent.GetFloat("Base", "OilReduceSpeed", "Value") * monoBase.BuffList[buffID].buffOverride.CurrentOverride;
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, -1 * (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    else
                    {
                        GameMgr.Get<IMonoManager>().ChangeHPValue(monoBase, (monoBase.BuffList[buffID].buffOverride.CurrentOverride) * int.Parse(monoBase.BuffList[buffID].BuffEffect.Split(':')[1].Split('|')[1]));
                    }
                    GameMgr.Get<IMonoManager>().JumpText(monoBase.Position, "\n" + ((monoBase.Attr == MonoAttribute.Oil) ? "免疫" : "") + "缓慢", Data.Instance.PrintColor[6]);
                }
            }
        }
        else
        {
            tmpTime -= Time.deltaTime;
        }

        //麻痹状态
        monoBase.monoRealtimeStatus.IsElectriciting = (monoBase.BuffList.ContainsKey(6));
        //致盲状态
        monoBase.monoRealtimeStatus.IsSteamed = (monoBase.BuffList.ContainsKey(5));

        //冻结状态
        if (monoBase.monoRealtimeStatus.IsFrozen > 0)
        {
            monoBase.monoRealtimeStatus.IsFrozen -= Time.deltaTime;
               FreezeRate = 0f;
        }
        else
        {
            monoBase.monoRealtimeStatus.IsFrozen = 0;
        }
    }
    private void UpdateBuffEffect()
    {
        foreach (Transform child in transform.Find("Sprite/Buff"))
        {
            switch (child.name)
            {
                case "Buff_Fire(Clone)":
                    CheckEmit(child, 1);
                    break;
                case "Buff_Ice(Clone)":
                    CheckEmit(child, 2);
                    break;
                case "Buff_Electric(Clone)":
                    CheckEmit(child, 6);
                    break;
                case "Buff_Oil(Clone)":
                    CheckEmit(child, 7);
                    break;
                case "Buff_Steam(Clone)":
                    CheckEmit(child, 5);
                    break;
                default:break;
            }
        }
    }
    private void CheckEmit(Transform child, int buffID)
    {
        var em = child.GetComponent<ParticleSystem>().emission;
        em.enabled = monoBase.BuffList.ContainsKey(buffID);
    }
    #endregion

    #region 颜色
    bool IsChangingColor;
    public void ColorControl()
    {
        if (GetComponentInChildren<SpriteRenderer>().color != GetAttrColor() && !IsChangingColor)
        {
            IsChangingColor = true;
            GetComponentInChildren<SpriteRenderer>().DOColor(GetAttrColor(), 0.25f).OnComplete(() => { IsChangingColor = false; });
        }
    }
    private Color GetAttrColor()
    {
        Color GetColor = new Color();
        switch (monoBase.Attr)
        {
            case MonoAttribute.None:
                GetColor = new Color(1, 1, 1, 1);
                break;
            case MonoAttribute.Fire:
                GetColor = Data.Instance.PrintColor[0];
                break;
            case MonoAttribute.Ice:
                GetColor = Data.Instance.PrintColor[1];
                break;
            case MonoAttribute.Shine:
                GetColor = Data.Instance.PrintColor[2];
                break;
            case MonoAttribute.Dark:
                GetColor = Data.Instance.PrintColor[3];
                break;
            case MonoAttribute.Steam:
                GetColor = Data.Instance.PrintColor[4];
                break;
            case MonoAttribute.Electric:
                GetColor = Data.Instance.PrintColor[5];
                break;
            case MonoAttribute.Oil:
                GetColor = Data.Instance.PrintColor[6];
                break;
            default:
                GetColor = new Color(1, 1, 1, 1);
                break;
        }
        return GetColor;
    }
    #endregion

    public void AnimationControl()
    {
        GetComponentInChildren<Animator>().SetBool("Walking", true);
        if (monoBase.Direction.y > 0)
        {
            if (Mathf.Abs(monoBase.Direction.x) <= monoBase.Direction.y)
            {
                GetComponentInChildren<Animator>().SetFloat("Blend", 0f);
                return;
            }
        }
        else
        {
            if (Mathf.Abs(monoBase.Direction.x) <= Mathf.Abs(monoBase.Direction.y))
            {
                GetComponentInChildren<Animator>().SetFloat("Blend", 0.33f);
                return;
            }
        }
        if (monoBase.Direction.x > 0)
        {
            if (Mathf.Abs(monoBase.Direction.y) < monoBase.Direction.x)
            {
                GetComponentInChildren<Animator>().SetFloat("Blend", 1f);
                return;
            }
        }
        else
        {
            if (Mathf.Abs(monoBase.Direction.y) < Mathf.Abs(monoBase.Direction.x))
            {
                GetComponentInChildren<Animator>().SetFloat("Blend", 0.66f);
                return;
            }
        }
    }

    public enum canMoveDir
    {
        Below,
        Above,
        Left,
        Right
    }
    public class AStart
    {
        public float sum;
        public float cost;
        public float estimate;
        public Vector3 position;
        public AStart parent;
        public AStart(Vector3 pos, AStart prt, float s = 0, float cst = 0, float est = 0)
        {
            position = pos;
            parent = prt;
            sum = s;
            cost = cst;
            estimate = est;
        }
    }
}
